﻿using AutoMapper;
using Mapster;
using SqlSugar;
using Zhp.Common.Extention;
using Zhp.Common.WebApp;
using Zhp.Entity.Sys;
using Zhp.IService.Sys;
using Zhp.Model.Sys;
using Zhp.Service.Base;
using Zhp.SqlSugar.Repository;

namespace Zhp.Service.Sys
{
    public class SysUserMenuService : BaseService<SysUserMenu>, ISysUserMenuService
    {
        IBaseRepository<SysMenu> _sysMenuRep;
        IBaseRepository<SysUserRole> _sysUserRole;
        IBaseRepository<SysRoleMenu> _sysRoleMenu;
        public SysUserMenuService(ICurrentUser currentUser, IBaseRepository<SysUserMenu> rep, IBaseRepository<SysMenu> sysMenuRep, IBaseRepository<SysUserRole> sysUserRole, IBaseRepository<SysRoleMenu> sysRoleMenu)
        {
            _currentUser = currentUser;
            _rep = rep;
            _sysMenuRep = sysMenuRep;
            _sysUserRole = sysUserRole;
            _sysRoleMenu = sysRoleMenu;
        }

        public async Task<(List<UserMenuModel>, List<string>)> GetUserMenu(long userId)
        {
            //所有菜单
            var allMenuList = await _sysMenuRep.GetListAsync();
            //查找角色中的用户和菜单
            var roleList = await _sysUserRole.GetListAsync(x => x.UserId == userId);
            var roleMenuList = await _sysRoleMenu.GetListAsync(x => roleList.Select(y => y.RoleId).Contains(x.RoleId));

            //用户在角色中分配的菜单
            var rList = allMenuList.Adapt<List<UserMenuModel>>();
            rList.ForEach(x => x.IsRoleMenu = roleMenuList.Exists(y => y.MenuId.Equals(x.Id)));
            rList = rList.ToTree(x => x.Id, x => x.Children, x => x.ParentId, null);

            var userMenuList = await _rep.GetListAsync(x => x.UserId == userId);
            var menuIdLeafList = allMenuList.Where(x => userMenuList.Select(x => x.MenuId).Contains(x.Id)).Select(x => x.Id.ToString()).ToList();

            //合并用户菜单和角色菜单
            var roleMenuIdLeafList = allMenuList.Where(x => roleMenuList.Select(y => y.MenuId).Distinct().Contains(x.Id)).Select(x => x.Id.ToString());
            menuIdLeafList.AddRange(roleMenuIdLeafList);

            return (rList, menuIdLeafList);
        }

        public async Task<bool> Create(UserMenuCreate create)
        {
            using (var uow = _rep.Context.CreateContext(_rep.Context.Ado.IsNoTran()))
            {
                await _rep.DeleteAsync(x => x.UserId == create.UserId);

                //查找角色中的用户和菜单，前端提交的时候有通过角色分配的菜单，被禁用了，也提交了，这里过滤掉
                var roleList = await _sysUserRole.GetListAsync(x => x.UserId == create.UserId);
                var roleMenuList = await _sysRoleMenu.GetListAsync(x => roleList.Select(y => y.RoleId).Contains(x.RoleId));
                create.MenuIdList.RemoveAll(x => roleMenuList.Exists(y => y.MenuId == x));

                var userMenuList = new List<SysUserMenu>();
                foreach (var item in create.MenuIdList)
                {
                    userMenuList.Add(new SysUserMenu
                    {
                        UserId = create.UserId,
                        MenuId = item,
                    });
                }
                await _rep.InsertRangeAsync(userMenuList);

                return uow.Commit();
            }
        }

        public async Task<bool> HasPermission(long userId, string menuUrl)
        {
            var roleList = await _sysUserRole.GetListAsync(x => x.UserId == userId);
            var roleMenuList = await _sysRoleMenu.GetListAsync(x => roleList.Select(y => y.RoleId).Contains(x.RoleId));

            var userMenuList = await _rep.GetListAsync(x => x.UserId == userId);

            var menuIdList = roleMenuList.Select(x => x.MenuId).Union(userMenuList.Select(x => x.MenuId));
            
            var menuList = await _sysMenuRep.GetListAsync(x => menuIdList.Contains(x.Id));

            return menuList.Exists(x => x.ApiUrl.ObjToString().ToLower().Contains(menuUrl));
        }
    }
}
